<?php

namespace catchAdmin\permissions\middleware;

use app\common\lib\Redis;
use catcher\Code;
use catcher\exceptions\CatchException;
use catcher\exceptions\FailedException;
use thans\jwt\exception\TokenBlacklistException;
use thans\jwt\exception\TokenExpiredException;
use thans\jwt\exception\TokenInvalidException;
use thans\jwt\facade\JWTAuth;
use think\Middleware;

class AuthTokenMiddleware extends Middleware
{
    public function handle($request, \Closure $next)
    {
        try {
            $filterInfo = ["user/info", "generate", "upload_record"];
            if (!in_array($request->pathInfo(), $filterInfo, true)) {
                $sign = $request->header("sign");
                $requestId = $request->header("requestId");
                //判断requestId是否已经存在于redis记录中
                if (empty($requestId) || Redis::getInstance()->redis->keys("doctor:" . $requestId)) {
                  //  throw new FailedException("非法请求r");
                }
                Redis::getInstance()->redis->setex("doctor:" . $requestId, 300, "OK");
                $authResult = JWTAuth::auth();
                $genRequestId = hash("sha256", $authResult["admin_id"] . "ZHYX" . $sign);
                if ($genRequestId !== $requestId) {
                  //  throw new FailedException("非法请求，伪造请求" . $genRequestId);
                }
            }
        } catch (\Exception $e) {

            if ($e instanceof TokenExpiredException) {
                throw new FailedException('token 过期', Code::LOGIN_EXPIRED);
            }
            if ($e instanceof TokenBlacklistException) {
                throw new FailedException('token 被加入黑名单', Code::LOGIN_BLACKLIST);
            }
            if ($e instanceof TokenInvalidException) {
                throw new FailedException('token 不合法', Code::LOST_LOGIN);
            }
            if ($e instanceof FailedException) {
                throw new FailedException($e->getMessage(), Code::FAILED);
            }
            throw new FailedException('登录用户不合法', Code::LOST_LOGIN);
        }
        return $next($request);
    }

    private function checkToken(string $userId, string $token): void
    {
        $userKey = hash("sha256", $userId . "_" . $_SERVER["REMOTE_ADDR"] . '_' . ($_SERVER["HTTP_USER_AGENT"] ?? ''));
        if (!Redis::getInstance()->redis->keys($userKey)) {
            throw new FailedException("登录过期", Code::LOGIN_EXPIRED);
        } else {
            $redisToken = Redis::getInstance()->redis->get($userKey);
            if ($redisToken !== $token) {
                throw new FailedException("非法登录", Code::USER_FORBIDDEN);
            }
        }
        //判断用户传过来的token是否是用户自己
        $redisToken = Redis::getInstance()->redis->get("jwt:user:" . $userId) ?? "";
        if ($redisToken !== $token) {
            throw new FailedException("非法登录", Code::USER_FORBIDDEN);
        }
        //判断token时间
        $ttl = Redis::getInstance()->redis->ttl($userKey);
        if ($ttl < 1800) {
            Redis::getInstance()->redis->expireat($userKey, time() + $ttl + 1800);
        }


    }
}
